package com.ww.springboot.boot.algorithm.leetcode1;

/**
 * 描述：
 *
 * @author 🧑 ‍wanwei
 * @since 2022-03-08 16:50
 */
public class NextPermutation {

    //方法2 比方法1 的优势在于 方法2的值本身就有顺序 只需要反转即可 无需排序
    public static void main(String[] args) {
        int[] nums = {2,1,2,2,2,2,2,1};
        nextPermutation(nums);

        //reverse(nums, 1);
        for (int i = 0; i < nums.length; i++) {
            System.out.println(nums[i]);
        }
    }

    public static void nextPermutation(int[] nums) {
        //反向查找 第一个右边值大于左边值的
        int i;
        for (i = nums.length - 1; i > 0; i--) {
            if (nums[i] > nums[i - 1]) {
                //找到了 则将右边大于 i 的最小值赋给左边 再将左边的所有值从小到大排序
                break;
            }
        }

        if (i == 0) {
            //未找到更大的 直接从小到大重排整个队列
            reverse(nums,0);
        } else {
            //将右边大于 i 的最小值赋给左边 再将左边的所有值从小到大排序
            int n = nums[i - 1];
            int j = nums.length - 1;
            //找一个比交换值 偏大的第一个值
            while(j>i && nums[i-1] >= nums[j]){
                j--;
            }
            //交换两数位置
            nums[i - 1] = nums[j];
            nums[j] = n;
            //将i后面的值从小到大重排整个队列
            reverse(nums,i);
        }
    }

    public static void nextPermutation2(int[] nums) {
        int i = nums.length - 2;
        while (i >= 0 && nums[i] >= nums[i + 1]) {
            i--;
        }
        if (i >= 0) {
            int j = nums.length - 1;
            while (j >= 0 && nums[i] >= nums[j]) {
                j--;
            }
            swap(nums, i, j);
        }
        reverse(nums, i + 1);
    }


    public static void swap(int[] nums, int i, int j) {
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }

    public static void reverse(int[] nums, int start) {
        int left = start, right = nums.length - 1;
        while (left < right) {
            swap(nums, left, right);
            left++;
            right--;
        }
    }
}
